package cn.dingd.simplenes;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;

//import cn.dingd.simplenes.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity implements View.OnTouchListener {

    // Used to load the 'simplenes' library on application startup.


    static final Object _neslock = new Object();

    // private ActivityMainBinding binding;
    private SimpleNes simpleNes;
    private Timer timer;
    private GameScreen gameScreen;
    private GamePadLeft gamePadLeft;
    private Button gamePad_reset;
    private Button gamePad_select;
    private Button gamePad_a;
    private Button gamePad_b;
    private AudioTrack audioTrack;

    private static final int KEY_A = 0;
    private static final int KEY_B = 1;
    private static final int KEY_SELECT = 2;
    private static final int KEY_RESET = 3;
    private static final int KEY_TOP = 4;
    private static final int KEY_BOTTOM = 5;
    private static final int KEY_LEFT = 6;
    private static final int KEY_RIGHT = 7;

    private int[] keyState = new int[8];

    private String TAG = MainActivity.class.getSimpleName();
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1) {

                gameScreen.update((byte[]) msg.obj);
                gameScreen.invalidate();
                // Log.d(TAG,"更新界面");
            }
        }
    };

    TimerTask task = new TimerTask() {
        @Override
        public void run() {
            // Log.d(TAG,"运行一次");
            synchronized (_neslock) {
//                for (int i = 0; i < 8; i++) {
//                    simpleNes.userinput(i, keyState[i]);
//                }
                simpleNes.emulationFrame();

            }
            short[] sample = simpleNes.getSamples();
            if (sample != null && sample.length > 0)
                audioTrack.write(sample, 0, sample.length);

            Message message = handler.obtainMessage();
            message.what = 1;
            message.obj = simpleNes.getCanvas();
            handler.sendMessage(message);
        }
    };
    private int mMinBufferSize;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
        //      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        // }
        super.onCreate(savedInstanceState);

        // binding = ActivityMainBinding.inflate(getLayoutInflater());
        //  setContentView(binding.getRoot());
        setContentView(R.layout.activity_main);


        //根据采样率，采样精度，单双声道来得到frame的大小。
        mMinBufferSize = AudioTrack.getMinBufferSize(44100,
                AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);//计算最小缓冲区
        //注意，按照数字音频的知识，这个算出来的是一秒钟buffer的大小。
        //创建AudioTrack
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
                AudioFormat.ENCODING_PCM_16BIT, mMinBufferSize, AudioTrack.MODE_STREAM);
        audioTrack.play();

        timer = new Timer();
        gameScreen = findViewById(R.id.game_screen);
        gamePadLeft = findViewById(R.id.gamepad_left);
        gamePad_reset = findViewById(R.id.gamepad_reset);
        gamePad_select = findViewById(R.id.gamepad_select);
        gamePad_a = findViewById(R.id.gamepad_a);
        gamePad_b = findViewById(R.id.gamepad_b);

        gamePad_reset.setOnTouchListener(this);
        gamePad_select.setOnTouchListener(this);
        gamePad_a.setOnTouchListener(this);
        gamePad_b.setOnTouchListener(this);

        gamePadLeft.setOnTouchListener((d, r) -> {
            if (d > 10) {
                double degrees = Math.toDegrees(r);
                //把遥感分为16个区域 判断当前位置
                int pos = (int) (degrees / (360 / 16));
                //  Log.d(TAG, "pos:" + pos);

                switch (pos) {
                    case 0:
                    case 15:
                    case 16:
                        simpleNes.userinput(KEY_TOP, 0);
                        simpleNes.userinput(KEY_LEFT, 0);
                        simpleNes.userinput(KEY_RIGHT, 1);
                        simpleNes.userinput(KEY_BOTTOM, 0);
                        break;
                    case 1:
                    case 2:
                        simpleNes.userinput(KEY_TOP, 1);
                        simpleNes.userinput(KEY_LEFT, 0);
                        simpleNes.userinput(KEY_RIGHT, 1);
                        simpleNes.userinput(KEY_BOTTOM, 0);
                        break;
                    case 3:
                    case 4:
                        simpleNes.userinput(KEY_TOP, 1);
                        simpleNes.userinput(KEY_LEFT, 0);
                        simpleNes.userinput(KEY_RIGHT, 0);
                        simpleNes.userinput(KEY_BOTTOM, 0);
                        break;
                    case 5:
                    case 6:
                        simpleNes.userinput(KEY_TOP, 1);
                        simpleNes.userinput(KEY_LEFT, 1);
                        simpleNes.userinput(KEY_RIGHT, 0);
                        simpleNes.userinput(KEY_BOTTOM, 0);
                        break;
                    case 7:
                    case 8:
                        simpleNes.userinput(KEY_TOP, 0);
                        simpleNes.userinput(KEY_LEFT, 1);
                        simpleNes.userinput(KEY_RIGHT, 0);
                        simpleNes.userinput(KEY_BOTTOM, 0);
                        break;
                    case 9:
                    case 10:
                        simpleNes.userinput(KEY_TOP, 0);
                        simpleNes.userinput(KEY_LEFT, 1);
                        simpleNes.userinput(KEY_RIGHT, 0);
                        simpleNes.userinput(KEY_BOTTOM, 1);
                        break;
                    case 11:
                    case 12:
                        simpleNes.userinput(KEY_TOP, 0);
                        simpleNes.userinput(KEY_LEFT, 0);
                        simpleNes.userinput(KEY_RIGHT, 0);
                        simpleNes.userinput(KEY_BOTTOM, 1);
                        break;
                    case 13:
                    case 14:
                        simpleNes.userinput(KEY_TOP, 0);
                        simpleNes.userinput(KEY_LEFT, 0);
                        simpleNes.userinput(KEY_RIGHT, 1);
                        simpleNes.userinput(KEY_BOTTOM, 1);
                        break;
                }
            } else {
                simpleNes.userinput(KEY_TOP, 0);
                simpleNes.userinput(KEY_LEFT, 0);
                simpleNes.userinput(KEY_RIGHT, 0);
                simpleNes.userinput(KEY_BOTTOM, 0);
            }
        });

        simpleNes = new SimpleNes();
        try {
            InputStream inputStream = getResources().getAssets().open("魂斗罗(美版).nes");
            byte[] bytes = new byte[16];
            inputStream.read(bytes, 0, 16);
            int size = simpleNes.validate(bytes);
            byte[] body = new byte[size];
            inputStream.read(body, 0, size);
            simpleNes.loadRom(body);
            simpleNes.reset();
            Log.d(TAG, "运行一次");
            timer.scheduleAtFixedRate(task, 0, 16);

        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            FileInputStream fin = new FileInputStream("");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            int id = v.getId();
            if (id == R.id.gamepad_a) {
                simpleNes.userinput(KEY_A, 1);
            } else if (id == R.id.gamepad_b) {
                simpleNes.userinput(KEY_B, 1);
            } else if (id == R.id.gamepad_select) {       //keyState[KEY_SELECT] = 1;
                simpleNes.userinput(KEY_SELECT, 1);
            } else if (id == R.id.gamepad_reset) {
                simpleNes.userinput(KEY_RESET, 1);
            }
        }
        if (event.getAction() == MotionEvent.ACTION_UP) {
            int id = v.getId();
            if (id == R.id.gamepad_a) {
                simpleNes.userinput(KEY_A, 0);
            } else if (id == R.id.gamepad_b) {
                simpleNes.userinput(KEY_B, 0);
            } else if (id == R.id.gamepad_select) {       //keyState[KEY_SELECT] = 1;
                simpleNes.userinput(KEY_SELECT, 0);
            } else if (id == R.id.gamepad_reset) {
                simpleNes.userinput(KEY_RESET, 0);
            }
        }
        return false;
    }

    @Override
    protected void onResume() {
        super.onResume();
        simpleNes.play();
    }

    @Override
    protected void onPause() {
        super.onPause();
        simpleNes.pause();
    }
}